import json
import re
import sys
import os

try:
    import requests
except ImportError:
    import subprocess
    import sys
    print("未检测到requests库，正在使用清华镜像自动安装...")
    subprocess.check_call([
        sys.executable, "-m", "pip", "install", "requests", "-i", "https://pypi.tuna.tsinghua.edu.cn/simple"
    ])
    import requests

import shutil

# ==============================================================================
# --- 配置区域  ---
# ==============================================================================

# miao-plugin绝对/相对路径。
MIAO_PLUGIN_PATH = "miao-plugin"
# 是否从API自动获取最新遗器ID。
FETCH_LATEST_IDS_FROM_API = True
RELIC_IDS_TO_PROCESS = []
API_URL_TEMPLATE = "https://api.hakush.in/hsr/data/cn/relicset/{}.json"
LATEST_IDS_API_URL = "https://api.hakush.in/hsr/new.json"
IMAGE_URL_TEMPLATE = "https://api.hakush.in/hsr/UI/relicfigures/IconRelic_{}_{}.webp"
ARTIFACT_DATA_PATH = os.path.join("resources", "meta-sr", "artifact", "data.json")
ELEMENT_TYPES = []

# ==============================================================================
# --- 核心代码  ---
# ==============================================================================

def sanitize_filename(name: str) -> str:
    """清理字符串中不适用于文件名或文件夹名的非法字符。"""
    return re.sub(r'[\\/*?:"<>|]', "", name).strip()

def download_relic_images(relic_id: str, set_name: str, part_keys: list, base_dir: str):
    """下载指定套装的所有部件图像。"""
    sanitized_set_name = sanitize_filename(set_name)
    if not sanitized_set_name:
        print(f"    - 错误: 套装名 '{set_name}' 清理后为空，无法创建文件夹。")
        return
    image_folder_path = os.path.join(base_dir, sanitized_set_name)
    os.makedirs(image_folder_path, exist_ok=True)
    print(f"    - 图像将保存在: {image_folder_path}")
    for part_key in part_keys:
        image_url = IMAGE_URL_TEMPLATE.format(relic_id, part_key)
        dest_filename = f"arti-{part_key}.webp"
        dest_filepath = os.path.join(image_folder_path, dest_filename)
        print(f"      - 正在下载 {dest_filename} ...")
        try:
            with requests.get(image_url, stream=True, timeout=15) as r:
                r.raise_for_status()
                with open(dest_filepath, 'wb') as f:
                    shutil.copyfileobj(r.raw, f)
        except Exception as e:
            print(f"      - 错误: 下载或保存图像失败: {e}")

def format_skill_desc(desc: str, params: list) -> str:
    """格式化技能描述字符串。"""
    def replacer(match):
        param_index = int(match.group(1)) - 1
        if 0 <= param_index < len(params):
            value = params[param_index]
            if isinstance(value, float) and value < 1.0: return "{:.1%}".format(value)
            else: return str(int(value))
        return match.group(0)
    formatted_desc = re.sub(r'#(\d+)(?:\[i\])?%?', replacer, desc)
    formatted_desc = formatted_desc.replace('<unbreak>', '<nobr>').replace('</unbreak>', '</nobr>')
    for element in ELEMENT_TYPES:
        if formatted_desc.startswith(element):
            formatted_desc = f"<span>{element}</span>" + formatted_desc[len(element):]; break
    return formatted_desc

def transform_data(source_data: dict, relic_id: str) -> dict:
    """将从API获取的源数据转换为目标data.json格式。"""
    transformed = {
        "id": relic_id, "name": source_data.get("Name", ""), "skills": {}, "idxs": {}
    }
    if "RequireNum" in source_data:
        for num, skill_info in source_data["RequireNum"].items():
            transformed["skills"][num] = format_skill_desc(skill_info.get("Desc", ""), skill_info.get("ParamList", []))
    if "Parts" in source_data:
        for part_id, part_data in source_data["Parts"].items():
            idx_key = part_id[-1]
            ids_dict = {}; base_id_suffix = part_id[1:]; rarity_map = {'3': 2, '4': 3, '5': 4, '6': 5}
            for prefix, rarity_level in rarity_map.items(): ids_dict[f"{prefix}{base_id_suffix}"] = rarity_level
            transformed["idxs"][idx_key] = {
                "name": part_data.get("Name", ""), "desc": part_data.get("Desc", ""),
                "lore": part_data.get("Story", "").replace('\\n\\n', '<br /><br />'), "ids": ids_dict
            }
    return transformed

def main():
    """主执行函数"""
    if not MIAO_PLUGIN_PATH or not os.path.isdir(MIAO_PLUGIN_PATH):
        print(f"错误: 配置的路径 '{MIAO_PLUGIN_PATH}' 无效。请在脚本中正确配置。")
        return


    ids_from_api = []
    if FETCH_LATEST_IDS_FROM_API:
        try:
            response = requests.get(LATEST_IDS_API_URL, timeout=10)
            response.raise_for_status()
            ids_from_api = [str(id_num) for id_num in response.json().get("relicset", [])]
            if ids_from_api:
                print(f"成功从API获取 {len(ids_from_api)} 个待处理ID: {', '.join(ids_from_api)}")
            else:
                print("从API获取的relicset列表为空。")
        except Exception as e:
            print(f"错误: 无法从API获取最新ID列表: {e}")

    ids_to_process = list({str(i) for i in (ids_from_api + RELIC_IDS_TO_PROCESS) if str(i)})
    if not ids_to_process:
        print("最终要处理的ID列表为空，脚本终止。")
        return

    target_path = os.path.join(MIAO_PLUGIN_PATH, ARTIFACT_DATA_PATH)
    print(f"\n目标JSON文件路径: {target_path}")

    print("\n开始处理ID列表（存在则覆盖，不存在则新增）...")
    processed_count = 0
    if os.path.exists(target_path):
        try:
            with open(target_path, 'r', encoding='utf-8') as f:
                all_data = json.load(f)
        except Exception:
            all_data = {}
    else:
        all_data = {}

    for relic_id in ids_to_process:
        print(f"--- 正在处理 ID: {relic_id} ---")
        api_url = API_URL_TEMPLATE.format(relic_id)
        try:
            response = requests.get(api_url, timeout=10)
            response.raise_for_status()
            source_data = response.json()
            new_relic_data = transform_data(source_data, relic_id)

            if relic_id in all_data:
                all_data[relic_id] = new_relic_data
                print(f"  - 已覆盖ID {relic_id} 的数据 ('{new_relic_data['name']}')。")
            else:
                all_data[relic_id] = new_relic_data
                print(f"  - 新增ID {relic_id} 的数据 ('{new_relic_data['name']}')。")
            processed_count += 1

            print(f"  - 开始处理图像下载...")
            set_name = new_relic_data['name']
            part_keys = new_relic_data['idxs'].keys()
            base_dir = os.path.dirname(target_path)
            download_relic_images(relic_id, set_name, part_keys, base_dir)
        except Exception as e:
            print(f"  - 错误: 处理ID {relic_id} 时发生错误: {e}。")

    if processed_count > 0:
        try:
            os.makedirs(os.path.dirname(target_path), exist_ok=True)
            # 按id升序写入
            sorted_items = sorted(all_data.items(), key=lambda x: int(x[0]))
            sorted_data = {k: v for k, v in sorted_items}
            with open(target_path, 'w', encoding='utf-8') as f:
                json.dump(sorted_data, f, indent=2, ensure_ascii=False, sort_keys=False)
            print(f"\n处理完成！JSON文件已按ID升序保存。")
            print(f"总共有 {processed_count} 个套装的数据被更新或添加。文件现在总共包含 {len(sorted_data)} 条数据。")
        except IOError as e:
            print(f"\n错误: 最终写入JSON文件失败: {e}")
    else:
        print("\n处理完成，本次没有需要更新或添加的套装。")

if __name__ == "__main__":
    main()